#ifndef AVALON_MOCKCLIENTCONNECTION_HPP
#define AVALON_MOCKCLIENTCONNECTION_HPP
#include "Avalon/IO/ClientConnection.hpp"
#include "Avalon/IOTests/IOTests.hpp"

namespace Avalon {
namespace IO {
namespace Tests {

  /** \class MockClientConnection
   *  \brief Implements ClientConnection for testing/mock purposes.
   */
  class MockClientConnection : public ClientConnection {
    public:

      //! Constructs a MockClientConnection.
      /*!
        \param server The MockServer to connect to.
        \param channel The channel used on the client end.
      */
      MockClientConnection(MockServerConnection* server,
        MockClientChannel* channel,
        const boost::shared_ptr<PipedReader>& serverReader,
        const boost::shared_ptr<PipedReader>& clientReader);

      virtual ~MockClientConnection();

      virtual void Open();

      virtual bool IsOpen() const;

      virtual void Close();

      virtual void SetClosedSlot(const ClosedSlot& slot, Out<bool> isOpen);

    private:
      friend class MockServerConnection;
      mutable boost::recursive_mutex m_mutex;
      mutable boost::condition_variable_any m_connectedCondition;
      MockServerConnection* m_server;
      MockClientChannel* m_channel;
      boost::shared_ptr<PipedReader> m_serverReader;
      boost::shared_ptr<PipedReader> m_clientReader;
      bool m_isOpen;
      mutable boost::shared_ptr<ClosedSlot> m_closedSlot;

      void AcceptConnection();
      void RejectConnection();
      void CloseConnection();
      Channel* CreateServerChannel();
  };
}
}
}

#endif // AVALON_MOCKCLIENTCONNECTION_HPP
